﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows.Media.Imaging;
using Microsoft.Phone.Scheduler;
using System.Windows.Navigation;

namespace WakeApp
{
    public partial class MainPage : PhoneApplicationPage
    {
        //storage dell'applicazione
        private static IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;

        //nome degli allarmi nello scheduler
        private string nextAlarmName = "WakeUpAlarm";

        private int svegliaSelezionata = -1;

        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }//costruttore MainPage

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            //estraggo la sveglia prossima
            if (appSettings.Contains("nextAlarm"))//ho una prossima sveglia settata
            {
                DateTime sveglia = (DateTime)appSettings["nextAlarm"];

                DateTime inizio = new DateTime(sveglia.Year, sveglia.Month, sveglia.Day,sveglia.Hour, sveglia.Minute, 0);
                DateTime fine = new DateTime(inizio.Ticks + (TimeSpan.TicksPerMinute * 20));
                DateTime oggi = DateTime.Now;

                if ((inizio.Ticks <= oggi.Ticks) && (oggi.Ticks <= fine.Ticks))//sta suonando la sveglia
                {
                    NavigationService.Navigate(new Uri("/Domanda.xaml", UriKind.Relative));//cambio della pagina
                }
            }

        }//OnNavigatedTo

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            listBox1.Items.Clear();

            Image[] ImageGiorni = new Image[7];
            TextBlock[] TextGiorni = new TextBlock[7];

            Style CanvasStyle = Application.Current.Resources["CanvasMain"] as Style;
            Style TimeStyle = Application.Current.Resources["OraMain"] as Style;
            Style ToogleStyle = Application.Current.Resources["ToggleSwichMain"] as Style;

            Style ImageONStyle = Application.Current.Resources["ImageMainON"] as Style;
            Style ImageOFFStyle = Application.Current.Resources["ImageMainOFF"] as Style;

            Style DayStyle = Application.Current.Resources["GiorniMain"] as Style;

            foreach(string key in appSettings.Keys)
            {
                if (key != "nextAlarm")// è una sveglia
                {
                    System.DateTime time;
                    bool[] gg = new bool[7];

                    //s = ora:min|giorni 

                    string[] ris = key.Split('|');
                    string ora = ris[0];
                    string giorni = ris[1];

                    time = System.DateTime.Parse(ora);

                    int j = 0;
                    foreach (char c in giorni)
                    {
                        gg[j] = (c == '1');//se il giorno è attivato ritorno true, false altrimenti
                        j++;
                    }

                    //creazione del contenitore
                    Canvas griglia = new Canvas();
                    griglia.Style = CanvasStyle;
                    griglia.Tag = key;

                    TextBlock TextOra = new TextBlock();
                    TextOra.Style = TimeStyle;
                    TextOra.Tag = key;
                    //TextOra.Tap+=new EventHandler<System.Windows.Input.GestureEventArgs>(Text_Tap);/////////////////////////
                
                    //controllo minuti ora
                    ris=ora.Split(':');
                    string hour = ris[0];
                    string minute = ris[1];

                    if (int.Parse(minute) < 10)
                        minute = "0" + minute;

                    TextOra.Text=hour+":"+minute;

                    //creazione dinamica ToggleSwitch in base alle sveglie
                    ToggleSwitch ts = new ToggleSwitch();
                    ts.Style = ToogleStyle;
                    ts.Tag = key;
                    ts.Foreground = new SolidColorBrush(Colors.Transparent);
                    ts.SwitchForeground = new SolidColorBrush(Color.FromArgb(255, 63, 92, 163));
                    ts.Background = new SolidColorBrush(Colors.Black);
                    ts.IsChecked = (appSettings[key].ToString() == "on");//se on ritorna true, false altrimenti
                    ts.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(ToggleSwitch_Tap);
                    ts.Click += new EventHandler<RoutedEventArgs>(ToggleSwitch_State);
                    ts.Checked += new EventHandler<RoutedEventArgs>(ToggleSwitch_State);
                    ts.Unchecked += new EventHandler<RoutedEventArgs>(ToggleSwitch_State);

                    //creazione giorni tutti a off
                    for (int igiorni = 0; igiorni < 7; igiorni++)
                    {
                        ImageGiorni[igiorni] = new Image();

                        if (gg[igiorni])
                            ImageGiorni[igiorni].Style = ImageONStyle;
                        else 
                            ImageGiorni[igiorni].Style = ImageOFFStyle;
                    
                        ImageGiorni[igiorni].Margin = new Thickness(12+igiorni*65,0,0,0);
                        //ImageGiorni[igiorni].Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(Image_Tap);///////////////////
                        ImageGiorni[igiorni].Tag = key;

                        TextGiorni[igiorni] = new TextBlock();
                        TextGiorni[igiorni].Style = DayStyle;
                        TextGiorni[igiorni].Margin = new Thickness(12 + igiorni * 65, 0, 0, 0);
                        //TextGiorni[igiorni].Tap+=new EventHandler<System.Windows.Input.GestureEventArgs>(Text_Tap);///////////////////
                        TextGiorni[igiorni].Tag = key;

                        griglia.Children.Add(ImageGiorni[igiorni]);
                        griglia.Children.Add(TextGiorni[igiorni]);
                    }//for

                    TextGiorni[0].Text = "Mon";
                    TextGiorni[1].Text = "Tue";
                    TextGiorni[2].Text = "Wed";
                    TextGiorni[3].Text = "Thu";
                    TextGiorni[4].Text = "Fri";
                    TextGiorni[5].Text = "Sat";
                    TextGiorni[6].Text = "Sun";

                    griglia.Children.Add(TextOra);
                    griglia.Children.Add(ts);

                    listBox1.Items.Add(griglia);
                }  
            }//for i

            if (listBox1.Items.Count <= 0)//vuoto
                listBox1.IsEnabled = false;
            else
                listBox1.IsEnabled = true;

            ModifyAlarm();
        }//load page

        private void ToggleSwitch_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            ToggleSwitch ts = sender as ToggleSwitch;
            string key = ts.Tag.ToString();
            

            if (appSettings[key].ToString() == "on")//se settato ad on ritorna true
            {
                appSettings[key] = "off";//cambio il valore
                ts.IsChecked = false;
            }
            else //se settato ad off ritorna false
            {
                appSettings[key] = "on";//cambio il valore
                ts.IsChecked = true;
            }

            ModifyAlarm();
        }//generic ToggleSwitch Tap

        private void ToggleSwitch_State(object sender, RoutedEventArgs e)
        {
            ToggleSwitch ts = sender as ToggleSwitch;
            string key = ts.Tag.ToString();

            if (appSettings[key].ToString() == "on")
            {
                ts.IsChecked = true;
            }
            else
            {
                ts.IsChecked = false;
            }
        }//generic Mantieni Stato

        private void buttonPiu_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/AggiungiSveglia.xaml", UriKind.Relative));//cambio della pagina
        }//buttonPiu_Click

        private void buttonImp_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/Impostazioni.xaml", UriKind.Relative));//cambio della pagina
        }//buttonImp_Click

        private void buttonInfo_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/PaginaInfo.xaml", UriKind.Relative));//cambio della pagina
        }//Click_info

        private void buttonRic_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/PaginaRiconoscimenti.xaml", UriKind.Relative));//cambio della pagina
        }//Click_ric

        private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            svegliaSelezionata = listBox1.SelectedIndex;
        }//listBox1_SelectionChanged

        private void listBox1_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            if (svegliaSelezionata >= 0)//è selezionato qualcosa
            {
                ListBox lb = sender as ListBox;
                Canvas sveglia = lb.Items.ElementAt(svegliaSelezionata) as Canvas;
                string key = sveglia.Tag.ToString();

                svegliaSelezionata = -1;

                NavigationService.Navigate(new Uri("/ModificaSveglia.xaml?key=" + key, UriKind.Relative));//cambio della pagina
            }
        }//listBox1_Tap

        private int indexOfWeek()
        {
            string s = DateTime.Now.DayOfWeek.ToString();
            switch (s)
            {
                case "Monday": return 0;
                case "Tuesday": return 1;
                case "Wednesday": return 2;
                case "Thursday": return 3;
                case "Friday": return 4;
                case "Saturday": return 5;
                case "Sunday": return 6;

                default: return 0;
            }
        }

        private DateTime fromStringToDateTime(string s)
        {
            string[] ris = s.Split(':');
            int ora = int.Parse(ris[0]);
            ris = ris[1].Split('|');
            int min = int.Parse(ris[0]);
            string settimana = ris[1];

            int indexOfToday = indexOfWeek();
            int annoAttuale = DateTime.Now.Year;
            int meseAttuale = DateTime.Now.Month;
            int giornoAttuale = DateTime.Now.Day;
            int oraAttuale = DateTime.Now.Hour;
            int minAttuale = DateTime.Now.Minute;

            bool trovato = false;

            if (settimana == "0000000")//sveglia in giornata
            {
                //controllo l'ora
                if (ora > oraAttuale || (ora == oraAttuale && min > minAttuale))//sveglia corretta
                {
                    //la sveglia è oggi
                    return new DateTime(annoAttuale, meseAttuale, giornoAttuale, ora, min, 0);
                }
                else
                {
                    //la sveglia è domani
                    DateTime temp = new DateTime(annoAttuale, meseAttuale, giornoAttuale, ora, min, 0);
                    return new DateTime(temp.Ticks + TimeSpan.TicksPerDay);
                }
            }
            else//ha almeno un 1 in settimana
            {
                if ((settimana[indexOfToday] == '1') && (ora > oraAttuale || (ora == oraAttuale && min > minAttuale)))//la sveglia è oggi
                {
                    return new DateTime(annoAttuale, meseAttuale, giornoAttuale, ora, min, 0);
                }
                else//la sveglia non è oggi
                {
                    int i = indexOfToday + 1;//parto da domani

                    while (!trovato)
                    {

                        if (settimana[i] == '1')
                        {
                            trovato = true;
                            int numDay = (((indexOfToday + i) % 7) + 1);

                            DateTime temp = new DateTime(annoAttuale, meseAttuale, giornoAttuale, ora, min, 0);
                            return new DateTime(temp.Ticks + TimeSpan.TicksPerDay * numDay);
                        }

                        if (i == indexOfToday)
                            break;

                        i = (i + 1) % 7;
                    }

                    MessageBox.Show("an unknow error has accured");//impossibile to happen
                }
            }

            return new DateTime();//impossibile to happen
        }//fromStringToDateTime

        private void ModifyAlarm()
        {
            if (appSettings.Contains("nextAlarm"))
            {
                appSettings.Remove("nextAlarm");

                //eliminare vecchie sveglie, se le trovo
                for (int i = 0; i < 20; i++)
                    if (ScheduledActionService.Find(nextAlarmName + i.ToString()) != null)//ho trovato una sveglia con questo nome
                    {
                        ScheduledActionService.Remove(nextAlarmName + i.ToString());//la rimuovo
                    }
            }

            if (appSettings.Count > 0)//esiste almeno una sveglia
            {
                DateTime min;
                string minKey = "";
                DateTime temp;

                foreach (string key in appSettings.Keys)//prendo la prima
                {
                    if (appSettings[key].ToString() == "on")
                    {
                        minKey = key;//salvo la chiave
                        break;
                    }
                }

                if (minKey != "")//almeno una a on
                {
                    min = fromStringToDateTime(minKey);

                    foreach (string key in appSettings.Keys)//mette in min la sveglia più prossima
                    {
                        if (appSettings[key].ToString() == "on")//guardo quelle attive
                        {
                            temp = fromStringToDateTime(key);

                            if (temp.Ticks < min.Ticks)
                            {
                                min = temp;//salvo il datetime
                                minKey = key;//e la chiave relativa alla sveglia
                            }
                        }
                    }

                    if (appSettings.Contains("nextAlarm"))//ho almeno un'altra sveglia dentro
                    {
                        appSettings["nextAlarm"] = min;//la sostituisco con la nuova prossima sveglia
                    }
                    else //se non c'è nulla è la prima sveglia
                    {
                        appSettings.Add("nextAlarm", min);//l'aggiungo
                    }

                    
                    //eliminare vecchie sveglie, se le trovo
                    for (int i = 0; i < 20; i++)
                        if (ScheduledActionService.Find(nextAlarmName + i.ToString()) != null)//ho trovato una sveglia con questo nome
                        {
                            ScheduledActionService.Remove(nextAlarmName + i.ToString());//la rimuovo
                        }

                    for (int i = 0; i < 20; i++)
                    {
                        DateTime supl = new DateTime(min.Ticks + (TimeSpan.TicksPerMinute * i));

                        Alarm sv = new Alarm(nextAlarmName + i.ToString());
                        sv.Content = "it's time to wake up my dear.";
                        sv.Sound = new Uri("Audio/elisa.wav", UriKind.Relative);
                        sv.BeginTime = supl;

                        ScheduledActionService.Add(sv);
                    }
                }
            }

        }//ModifyAlarm

        private void Text_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            TextBlock tb = sender as TextBlock;
            string key = tb.Tag.ToString();

            NavigationService.Navigate(new Uri("/ModificaSveglia.xaml?key=" + key, UriKind.Relative));//cambio della pagina
        }

        private void Image_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            Image i = sender as Image;
            string key = i.Tag.ToString();

            NavigationService.Navigate(new Uri("/ModificaSveglia.xaml?key=" + key, UriKind.Relative));//cambio della pagina
        }

    }//MainPage
}